﻿using System;
using System.Collections.Generic;
using Runtime.Services.Battle.Entity;

namespace Runtime.Models {

    /// <summary>
    /// 目标数据集
    /// </summary>
    public interface IDFR_ReadOnlyBattleAttackTargetDictionaryModelTD : IDFR_ReadOnlyDictionaryModel<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelTD> {

        new IDFR_BattleAttackTargetDictionaryModelTD AsReadWrite();

        IDFR_ReadOnlyBattleAttackTargetDictionaryModelBase AsBase();
    }

    /// <summary>
    /// 目标数据集
    /// </summary>
    public interface IDFR_BattleAttackTargetDictionaryModelTD : IDFR_ReadOnlyBattleAttackTargetDictionaryModelTD, IDFR_DictionaryModel<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelTD> {

        new IDFR_BattleAttackTargetDictionaryModelBase AsBase();
    }

    [Implement(typeof(IDFR_ReadOnlyBattleAttackTargetDictionaryModelTD))]
    [Implement(typeof(IDFR_ReadOnlyBattleAttackTargetDictionaryModelBase))]
    [Implement(typeof(IDFR_ReadOnlyDictionaryModel<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelTD>))]
    [Implement(typeof(IDFR_ReadOnlyDictionaryModel<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>))]
    [Implement(typeof(IDFR_BattleAttackTargetDictionaryModelTD))]
    [Implement(typeof(IDFR_BattleAttackTargetDictionaryModelBase))]
    [Implement(typeof(IDFR_DictionaryModel<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelTD>))]
    [Implement(typeof(IDFR_DictionaryModel<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>))]
    internal sealed class DFR_BattleAttackTargetDictionaryModelTD : DFR_DictionaryModel<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelTD>,
        IDFR_ReadOnlyBattleAttackTargetDictionaryModelTD, IDFR_BattleAttackTargetDictionaryModelTD,
        IDFR_ReadOnlyBattleAttackTargetDictionaryModelBase, IDFR_BattleAttackTargetDictionaryModelBase {

        public new IDFR_BattleAttackTargetDictionaryModelTD AsReadWrite() => this;
        IDFR_BattleAttackTargetDictionaryModelBase IDFR_ReadOnlyBattleAttackTargetDictionaryModelBase.AsReadWrite() => this;
        IDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase> IReadOnlyDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.AsReadWrite() => this;
        IReadOnlyDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase> IDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.AsReadOnly() => this;
        public IDFR_ReadOnlyBattleAttackTargetDictionaryModelBase AsBase() => this;
        IDFR_BattleAttackTargetDictionaryModelBase IDFR_BattleAttackTargetDictionaryModelTD.AsBase() => this;

        public DFR_BattleAttackTargetDictionaryModelTD() : base() {
            Updated += (key, oldValue, newValue) => m_Updated?.Invoke(key, oldValue, newValue);
            Added += (key, value) => m_Added?.Invoke(key, value);
            Removed += (key, value) => m_Removed?.Invoke(key, value);
            Cleared += () => m_Cleared?.Invoke();
        }

        protected override void Dispose() {
            m_Updated = null;
            m_Added = null;
            m_Removed = null;
            m_Cleared = null;
            base.Dispose();
        }

        IDFR_BattleAttackTargetModelBase IReadOnlyDictionary<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.this[DFR_BattleEntityInstanceID key] => base[key];

        IDFR_BattleAttackTargetModelBase IDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.this[DFR_BattleEntityInstanceID key] {
            get => base[key];
            set => base[key] = (IDFR_BattleAttackTargetModelTD)value;
        }
        IDFR_BattleAttackTargetModelBase IDictionary<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.this[DFR_BattleEntityInstanceID key] {
            get => base[key];
            set => base[key] = (IDFR_BattleAttackTargetModelTD)value;
        }

        IEnumerable<DFR_BattleEntityInstanceID> IReadOnlyDictionary<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Keys => Keys;

        IEnumerable<IDFR_BattleAttackTargetModelBase> IReadOnlyDictionary<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Values => Values;

        ICollection<IDFR_BattleAttackTargetModelBase> IDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Values => throw new NotImplementedException("由于ICollection 存在可写，不可逆变，使用只读相关接口完成逆变");

        ICollection<IDFR_BattleAttackTargetModelBase> IDictionary<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Values => throw new NotImplementedException("由于ICollection 存在可写，不可逆变，使用只读相关接口完成逆变");

        private event IDictionaryDataUpdated<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.UpdatedDelegate m_Updated;
        event IDictionaryDataUpdated<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.UpdatedDelegate IDictionaryDataUpdated<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Updated {
            add => m_Updated += value;
            remove => m_Updated -= value;
        }

        private event IDictionaryDataAdded<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.AddedDelegate m_Added;
        event IDictionaryDataAdded<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.AddedDelegate IDictionaryDataAdded<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Added {
            add => m_Added += value;
            remove => m_Added -= value;
        }

        private event IDictionaryDataRemoved<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.RemovedDelegate m_Removed;
        event IDictionaryDataRemoved<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.RemovedDelegate IDictionaryDataRemoved<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Removed {
            add => m_Removed += value;
            remove => m_Removed -= value;
        }

        private event IDictionaryDataCleared<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.ClearedDelegate m_Cleared;
        event IDictionaryDataCleared<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.ClearedDelegate IDictionaryDataCleared<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Cleared {
            add => m_Cleared += value;
            remove => m_Cleared -= value;
        }

        void IDictionary<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Add(DFR_BattleEntityInstanceID key, IDFR_BattleAttackTargetModelBase value) => Add(key, (IDFR_BattleAttackTargetModelTD)value);

        void ICollection<KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>>.Add(KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase> item) => Add(KeyValuePair.Create(item.Key, (IDFR_BattleAttackTargetModelTD)item.Value));

        bool ICollection<KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>>.Contains(KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase> item) => Contains(KeyValuePair.Create(item.Key, (IDFR_BattleAttackTargetModelTD)item.Value));

        void ICollection<KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>>.CopyTo(KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>[] array, int arrayIndex) {
            foreach (var key in Keys) {
                array[arrayIndex++] = KeyValuePair.Create(key, (IDFR_BattleAttackTargetModelBase)this[key]);
            }
        }

        IEnumerator<KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>> IEnumerable<KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>>.GetEnumerator() {
            foreach (var key in Keys) {
                yield return KeyValuePair.Create(key, (IDFR_BattleAttackTargetModelBase)this[key]);
            }
        }

        IDFR_BattleAttackTargetModelBase IReadOnlyDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.GetValue(DFR_BattleEntityInstanceID key) => GetValue(key);

        bool ICollection<KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>>.Remove(KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase> item) => Remove(KeyValuePair.Create(item.Key, (IDFR_BattleAttackTargetModelTD)item.Value));

        bool IDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.TryAdd(DFR_BattleEntityInstanceID key, IDFR_BattleAttackTargetModelBase value) => TryAdd(key, (IDFR_BattleAttackTargetModelTD)value);

        bool IDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.TryAdd(KeyValuePair<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase> item) => TryAdd(KeyValuePair.Create(item.Key, (IDFR_BattleAttackTargetModelTD)item.Value));

        bool IReadOnlyDictionary<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.TryGetValue(DFR_BattleEntityInstanceID key, out IDFR_BattleAttackTargetModelBase value) {
            if (TryGetValue(key, out var result)) {
                value = result;
                return true;
            }
            value = default;
            return false;
        }

        bool IDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.TryGetValue(DFR_BattleEntityInstanceID key, out IDFR_BattleAttackTargetModelBase value) {
            if (TryGetValue(key, out var result)) {
                value = result;
                return true;
            }
            value = default;
            return false;
        }

        bool IDictionary<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.TryGetValue(DFR_BattleEntityInstanceID key, out IDFR_BattleAttackTargetModelBase value) {
            if (TryGetValue(key, out var result)) {
                value = result;
                return true;
            }
            value = default;
            return false;
        }

        void IFixedLengthDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Update(DFR_BattleEntityInstanceID key, IDFR_BattleAttackTargetModelBase value) => Update(key, (IDFR_BattleAttackTargetModelTD)value);

        void IFixedLengthDictionaryData<DFR_BattleEntityInstanceID, IDFR_BattleAttackTargetModelBase>.Update(DFR_BattleEntityInstanceID key, Action<IDFR_BattleAttackTargetModelBase> updater) => Update(key, updater);
    }
}
